package com.laundry.shared.security

import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import android.provider.Settings
import java.io.File
import java.security.MessageDigest
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.SecretKey
import javax.crypto.spec.SecretKeySpec
import kotlin.random.Random

/**
 * 应用安全管理器
 */
class AppSecurityManager(private val context: Context) {
    
    companion object {
        private const val ALGORITHM = "AES"
        private const val TRANSFORMATION = "AES/ECB/PKCS5Padding"
        private const val KEY_ALIAS = "LaundryAppKey"
    }
    
    /**
     * 检查应用完整性
     */
    fun checkAppIntegrity(): SecurityCheckResult {
        val checks = mutableListOf<SecurityCheck>()
        
        // 1. 检查签名
        checks.add(checkAppSignature())
        
        // 2. 检查是否被调试
        checks.add(checkDebugging())
        
        // 3. 检查Root状态
        checks.add(checkRootStatus())
        
        // 4. 检查模拟器
        checks.add(checkEmulator())
        
        // 5. 检查Hook框架
        checks.add(checkHookFramework())
        
        // 6. 检查应用篡改
        checks.add(checkAppTampering())
        
        val failedChecks = checks.filter { !it.passed }
        val riskLevel = calculateRiskLevel(failedChecks)
        
        return SecurityCheckResult(
            passed = failedChecks.isEmpty(),
            riskLevel = riskLevel,
            failedChecks = failedChecks,
            recommendations = generateRecommendations(failedChecks)
        )
    }
    
    /**
     * 检查应用签名
     */
    private fun checkAppSignature(): SecurityCheck {
        return try {
            val packageInfo = context.packageManager.getPackageInfo(
                context.packageName,
                PackageManager.GET_SIGNATURES
            )
            
            val signatures = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                packageInfo.signingInfo?.apkContentsSigners
            } else {
                @Suppress("DEPRECATION")
                packageInfo.signatures
            }
            
            val expectedSignature = getExpectedSignature()
            val currentSignature = signatures?.firstOrNull()?.toCharsString()
            
            val isValid = currentSignature == expectedSignature
            
            SecurityCheck(
                name = "应用签名验证",
                passed = isValid,
                description = if (isValid) "应用签名验证通过" else "应用签名验证失败，可能被重新打包",
                riskLevel = if (isValid) RiskLevel.SAFE else RiskLevel.HIGH
            )
            
        } catch (e: Exception) {
            SecurityCheck(
                name = "应用签名验证",
                passed = false,
                description = "签名验证异常: ${e.message}",
                riskLevel = RiskLevel.HIGH
            )
        }
    }
    
    /**
     * 检查调试状态
     */
    private fun checkDebugging(): SecurityCheck {
        val isDebuggable = (context.applicationInfo.flags and android.content.pm.ApplicationInfo.FLAG_DEBUGGABLE) != 0
        val isDebuggerConnected = android.os.Debug.isDebuggerConnected()
        
        val isBeingDebugged = isDebuggable || isDebuggerConnected
        
        return SecurityCheck(
            name = "调试检测",
            passed = !isBeingDebugged,
            description = if (isBeingDebugged) "检测到应用正在被调试" else "未检测到调试行为",
            riskLevel = if (isBeingDebugged) RiskLevel.HIGH else RiskLevel.SAFE
        )
    }
    
    /**
     * 检查Root状态
     */
    private fun checkRootStatus(): SecurityCheck {
        val isRooted = isDeviceRooted()
        
        return SecurityCheck(
            name = "Root检测",
            passed = !isRooted,
            description = if (isRooted) "检测到设备已Root" else "设备未Root",
            riskLevel = if (isRooted) RiskLevel.MEDIUM else RiskLevel.SAFE
        )
    }
    
    /**
     * 检查模拟器
     */
    private fun checkEmulator(): SecurityCheck {
        val isEmulator = isRunningOnEmulator()
        
        return SecurityCheck(
            name = "模拟器检测",
            passed = !isEmulator,
            description = if (isEmulator) "检测到运行在模拟器上" else "运行在真实设备上",
            riskLevel = if (isEmulator) RiskLevel.MEDIUM else RiskLevel.SAFE
        )
    }
    
    /**
     * 检查Hook框架
     */
    private fun checkHookFramework(): SecurityCheck {
        val hasHookFramework = detectHookFramework()
        
        return SecurityCheck(
            name = "Hook框架检测",
            passed = !hasHookFramework,
            description = if (hasHookFramework) "检测到Hook框架" else "未检测到Hook框架",
            riskLevel = if (hasHookFramework) RiskLevel.HIGH else RiskLevel.SAFE
        )
    }
    
    /**
     * 检查应用篡改
     */
    private fun checkAppTampering(): SecurityCheck {
        val isTampered = detectAppTampering()
        
        return SecurityCheck(
            name = "应用篡改检测",
            passed = !isTampered,
            description = if (isTampered) "检测到应用被篡改" else "应用完整性正常",
            riskLevel = if (isTampered) RiskLevel.HIGH else RiskLevel.SAFE
        )
    }
    
    /**
     * 检测设备是否Root
     */
    private fun isDeviceRooted(): Boolean {
        // 检查常见的Root文件
        val rootPaths = arrayOf(
            "/system/app/Superuser.apk",
            "/sbin/su",
            "/system/bin/su",
            "/system/xbin/su",
            "/data/local/xbin/su",
            "/data/local/bin/su",
            "/system/sd/xbin/su",
            "/system/bin/failsafe/su",
            "/data/local/su",
            "/su/bin/su"
        )
        
        for (path in rootPaths) {
            if (File(path).exists()) {
                return true
            }
        }
        
        // 检查Root管理应用
        val rootApps = arrayOf(
            "com.noshufou.android.su",
            "com.noshufou.android.su.elite",
            "eu.chainfire.supersu",
            "com.koushikdutta.superuser",
            "com.thirdparty.superuser",
            "com.yellowes.su",
            "com.topjohnwu.magisk"
        )
        
        for (packageName in rootApps) {
            try {
                context.packageManager.getPackageInfo(packageName, 0)
                return true
            } catch (e: PackageManager.NameNotFoundException) {
                // 应用不存在，继续检查
            }
        }
        
        // 检查系统属性
        val buildTags = Build.TAGS
        if (buildTags != null && buildTags.contains("test-keys")) {
            return true
        }
        
        return false
    }
    
    /**
     * 检测是否运行在模拟器上
     */
    private fun isRunningOnEmulator(): Boolean {
        return (Build.FINGERPRINT.startsWith("generic") ||
                Build.FINGERPRINT.startsWith("unknown") ||
                Build.MODEL.contains("google_sdk") ||
                Build.MODEL.contains("Emulator") ||
                Build.MODEL.contains("Android SDK built for x86") ||
                Build.MANUFACTURER.contains("Genymotion") ||
                Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic") ||
                "google_sdk" == Build.PRODUCT ||
                Build.HARDWARE.contains("goldfish") ||
                Build.HARDWARE.contains("ranchu"))
    }
    
    /**
     * 检测Hook框架
     */
    private fun detectHookFramework(): Boolean {
        // 检查Xposed框架
        try {
            Class.forName("de.robv.android.xposed.XposedHelpers")
            return true
        } catch (e: ClassNotFoundException) {
            // Xposed未检测到
        }
        
        // 检查Frida
        try {
            val runtime = Runtime.getRuntime()
            val process = runtime.exec("ps")
            val reader = process.inputStream.bufferedReader()
            val output = reader.readText()
            if (output.contains("frida")) {
                return true
            }
        } catch (e: Exception) {
            // 检查失败
        }
        
        // 检查其他Hook框架的特征
        val hookLibraries = arrayOf(
            "libxposed_art.so",
            "libxposed_dalvik.so",
            "libsubstrate.so",
            "libsubstrate-dvm.so"
        )
        
        for (lib in hookLibraries) {
            try {
                System.loadLibrary(lib)
                return true
            } catch (e: UnsatisfiedLinkError) {
                // 库不存在，继续检查
            }
        }
        
        return false
    }
    
    /**
     * 检测应用篡改
     */
    private fun detectAppTampering(): Boolean {
        try {
            // 检查APK文件的校验和
            val packageInfo = context.packageManager.getPackageInfo(context.packageName, 0)
            val apkPath = packageInfo.applicationInfo.sourceDir
            val apkFile = File(apkPath)
            
            if (!apkFile.exists()) {
                return true
            }
            
            // 计算APK文件的MD5
            val currentHash = calculateFileMD5(apkFile)
            val expectedHash = getExpectedApkHash()
            
            return currentHash != expectedHash
            
        } catch (e: Exception) {
            return true // 检查失败视为篡改
        }
    }
    
    /**
     * 计算文件MD5
     */
    private fun calculateFileMD5(file: File): String {
        val digest = MessageDigest.getInstance("MD5")
        file.inputStream().use { inputStream ->
            val buffer = ByteArray(8192)
            var bytesRead: Int
            while (inputStream.read(buffer).also { bytesRead = it } != -1) {
                digest.update(buffer, 0, bytesRead)
            }
        }
        return digest.digest().joinToString("") { "%02x".format(it) }
    }
    
    /**
     * 计算风险等级
     */
    private fun calculateRiskLevel(failedChecks: List<SecurityCheck>): RiskLevel {
        if (failedChecks.isEmpty()) {
            return RiskLevel.SAFE
        }
        
        val highRiskCount = failedChecks.count { it.riskLevel == RiskLevel.HIGH }
        val mediumRiskCount = failedChecks.count { it.riskLevel == RiskLevel.MEDIUM }
        
        return when {
            highRiskCount >= 2 -> RiskLevel.CRITICAL
            highRiskCount >= 1 -> RiskLevel.HIGH
            mediumRiskCount >= 2 -> RiskLevel.MEDIUM
            else -> RiskLevel.LOW
        }
    }
    
    /**
     * 生成安全建议
     */
    private fun generateRecommendations(failedChecks: List<SecurityCheck>): List<String> {
        val recommendations = mutableListOf<String>()
        
        failedChecks.forEach { check ->
            when (check.name) {
                "应用签名验证" -> recommendations.add("请从官方渠道下载应用")
                "调试检测" -> recommendations.add("请关闭调试模式")
                "Root检测" -> recommendations.add("建议在非Root设备上使用")
                "模拟器检测" -> recommendations.add("建议在真实设备上使用")
                "Hook框架检测" -> recommendations.add("请卸载Hook框架")
                "应用篡改检测" -> recommendations.add("请重新安装官方版本")
            }
        }
        
        return recommendations
    }
    
    /**
     * 数据加密
     */
    fun encryptData(data: String, key: String): String {
        return try {
            val secretKey = SecretKeySpec(key.toByteArray(), ALGORITHM)
            val cipher = Cipher.getInstance(TRANSFORMATION)
            cipher.init(Cipher.ENCRYPT_MODE, secretKey)
            val encryptedData = cipher.doFinal(data.toByteArray())
            android.util.Base64.encodeToString(encryptedData, android.util.Base64.DEFAULT)
        } catch (e: Exception) {
            ""
        }
    }
    
    /**
     * 数据解密
     */
    fun decryptData(encryptedData: String, key: String): String {
        return try {
            val secretKey = SecretKeySpec(key.toByteArray(), ALGORITHM)
            val cipher = Cipher.getInstance(TRANSFORMATION)
            cipher.init(Cipher.DECRYPT_MODE, secretKey)
            val decodedData = android.util.Base64.decode(encryptedData, android.util.Base64.DEFAULT)
            val decryptedData = cipher.doFinal(decodedData)
            String(decryptedData)
        } catch (e: Exception) {
            ""
        }
    }
    
    /**
     * 生成随机密钥
     */
    fun generateRandomKey(): String {
        val keyGenerator = KeyGenerator.getInstance(ALGORITHM)
        keyGenerator.init(256)
        val secretKey = keyGenerator.generateKey()
        return android.util.Base64.encodeToString(secretKey.encoded, android.util.Base64.DEFAULT)
    }
    
    // 私有方法 - 这些应该从安全的地方获取
    private fun getExpectedSignature(): String {
        // 这里应该返回应用的预期签名
        return "expected_signature_hash"
    }
    
    private fun getExpectedApkHash(): String {
        // 这里应该返回APK的预期哈希值
        return "expected_apk_hash"
    }
}

// 数据模型
data class SecurityCheckResult(
    val passed: Boolean,
    val riskLevel: RiskLevel,
    val failedChecks: List<SecurityCheck>,
    val recommendations: List<String>
)

data class SecurityCheck(
    val name: String,
    val passed: Boolean,
    val description: String,
    val riskLevel: RiskLevel
)

enum class RiskLevel {
    SAFE,       // 安全
    LOW,        // 低风险
    MEDIUM,     // 中风险
    HIGH,       // 高风险
    CRITICAL    // 严重风险
}
